#!/usr/bin/env bash

source "$rvm_scripts_path/base"

rvm_is_not_a_shell_function=0 # for nested invocations of rvm

if [[ -n "${rvm_in_flag}" && -d "${rvm_in_flag}" ]]
then __rvm_cd "${rvm_in_flag}"
fi

__rvm_attempt_single_exec()
{
  # Return if we have multiple rubies. or we're not running exec.
  if (( ${#rvm_ruby_strings[@]} == 1 ))
  then
    __rvm_become "$rvm_ruby_strings"
    __rvm_load_rvmrc
    export rvm_project_rvmrc=0
    exec "${args[@]}"
  fi

  return 1
}

__rvm_ruby_do()
{
  # Return on invalid rubies.
  __rvm_become "$current_set_ruby" || return 1

  rvm_hook="before_do"
  source "$rvm_scripts_path/hook"

  if [[ -n "$rvm_json_flag" || -n "$rvm_yaml_flag" || -n "$rvm_summary_flag" ]]
  then
    if [[ ! -d "./log/$rvm_ruby_string/" ]]
    then
      mkdir -p "./log/$rvm_ruby_string/"
    fi
    touch "./log/$rvm_ruby_string/$action.log"
    "${args[@]}" >> "./log/$rvm_ruby_string/$action.log" 2>&1
  else
    if (( ${rvm_verbose_flag:-0} > 0 ))
    then
      current_env="$(__rvm_env_string)"
      if [[ "$current_env" != "$current_set_ruby" ]]
      then
        current_env="$current_set_ruby ($current_env)"
      fi
      rvm_log "$current_env: $(ruby -v $rvm_ruby_mode | \command \tr "\n" ' ')"
      unset current_env
    fi
    (
      __rvm_load_rvmrc
      export rvm_project_rvmrc=0
      "${args[@]}"
    )
  fi
  result=$?

  string=$rvm_ruby_string #$(basename $rvm_ruby_gem_home)

  if (( result == 0 ))
  then
    eval "successes=(${successes[*]} $string)"
  else
    eval "errors=(${errors[*]} $string)"
  fi
  eval "rubies=(${rubies[*]} $string)"
  eval "statuses=(${statuses[*]} $result)"
  unset string

  rvm_hook="after_do"
  source "$rvm_scripts_path/hook"
  __rvm_unset_ruby_variables
}

# Output the summary in a human readable format.
__rvm_summary()
{
  export successes errors statuses

  summary="\nSummary:\n\n"

  if [[ ${#successes[*]} -gt 0 ]]
  then
    if rvm_pretty_print stdout
    then
      summary="$summary ${rvm_notify_clr:-}${#successes[*]} successful: $(echo "${successes[*]}" | __rvm_sed 's# #, #g')${rvm_reset_clr:-}\n"
    else
      summary="$summary ${#successes[*]} successful: $(echo "${successes[*]}" | __rvm_sed 's# #, #g')\n"
    fi
  fi

  if [[ ${#errors[*]} -gt 0 ]] ; then
    if rvm_pretty_print stdout
    then
      summary="$summary ${rvm_error_clr:-}${#errors[*]} errors: $(echo "${errors[*]}" | __rvm_sed 's# #, #g')${rvm_reset_clr:-}\n"
    else
      summary="$summary ${#errors[*]} errors: $(echo "${errors[*]}" | __rvm_sed 's# #, #g')\n"
    fi
  fi

  total=${#rubies[*]}

  [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$?

  printf "%b" "$summary" | tee -a log/summary.log

  return ${#errors[*]}

}

# Output the summary in a yaml format.
__rvm_yaml()
{
  export successes errors statuses
  yaml="totals:\n  rubies: ${#rubies[*]}\n  successes: ${#successes[*]}\n  errors: ${#errors[*]}\nsuccesses:"

  for var in ${successes[*]} ; do yaml="$yaml\n  - $var" ; done
  yaml="$yaml\nerrors:"

  for var in ${errors[*]} ; do yaml="$yaml\n  - $var" ; done
  yaml="$yaml\nrubies:"
  total=${#rubies[*]}

  [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$?

  for (( index = $array_start ; index < $total + $array_start ; index++ )) ; do
    if [[ ${rvm_debug_flag:-0} -gt 0 ]] ; then
      rvm_debug "${rubies[$index]}: ${statuses[$index]}"
    fi
    yaml="$yaml\n  \"${rubies[$index]}\": ${statuses[$index]}"
  done
  unset index array_start

  \command \mkdir -p log

  printf "%b" "$yaml" | tee -a log/summary.yaml

  return ${#errors[*]}
}

# Output the summary in a json format.
__rvm_json()
{
  \typeset index array_start

  json="{
\"totals\": { \"rubies\": ${#rubies[*]}, \"successes\": ${#successes[*]}, \"errors\": ${#errors[*]} },
\"successful\": [$(echo \"${successes[*]}\" | __rvm_sed 's# #", "#g' | __rvm_sed 's#\"\"##')],
\"errors\": [$(echo \"${errors[*]}\" | __rvm_sed 's# #", "#g' | __rvm_sed 's#\"\"##')],
\"rubies\": { "

  total=${#rubies[*]}
  [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$?

  for (( index = $array_start ; index < $total + $array_start ; index++ )) ; do
    if [[ ${rvm_debug_flag:-0} -gt 0 ]] ; then
      rvm_debug "${rubies[$index]}: ${statuses[$index]}"
    fi
    json="$json\n    {\"${rubies[$index]}\": ${statuses[$index]}}"
    if (( $index + 1 < $total + $array_start )) ; then json="$json,  " ; fi
  done

  json="$json\n  }\n}"

  if [[ ! -d log ]] ; then
    mkdir -p log
  fi
  printf "%b" "$json" | tee -a log/summary.json

  return ${#errors[*]}
}

# Loop over a set or all rvm installed rubies to perform some action.
# Record the results and report based on CLI selections.

rubies=() ; successes=() ; errors=() ; statuses=()

args=( "$@" )
action="${args[$__array_start]}"
unset args[$__array_start]
args=( "${args[@]}" )

if [[ -z "$action" ]]
then
  rvm_error "Action must be specified."
  exit 1
elif [[ "$action" != "do" ]]
then
  rvm_error "Only 'do' action is allowed."
  exit 1
fi

# deprecated 2011.10.22 for RVM 1.9.0, removed 2012.09.13 for RVM 1.16.0
if [[ -z "${rvm_ruby_strings}" ]]
then
  rvm_error "\`rvm do ${args[@]}\` was removed, use \`rvm 1.9.2,1.9.3 do ${args[@]}\` or \`rvm all do ${args[@]}\` instead."
  exit 1
fi

previous_rvm_ruby_strings="$rvm_ruby_strings"
rvm_ruby_strings=( $( __rvm_expand_ruby_string "$rvm_ruby_strings" ) ) || {
  \typeset result=$?
  if
    [[ $result -eq 2 && -n "${rvm_expected_gemset_name:-${rvm_gemset_name:-}}" ]]
  then
    rvm_ruby_string="${previous_rvm_ruby_strings## }"
    __rvm_ruby_string
    rvm_error "Gemset '${rvm_expected_gemset_name:-${rvm_gemset_name:-}}' does not exist, \
'rvm $rvm_ruby_string do rvm gemset create ${rvm_expected_gemset_name:-${rvm_gemset_name:-}}' first, or append '--create'."
  else
    rvm_ruby_string="${previous_rvm_ruby_strings## }"
    __rvm_ruby_string
    rvm_error "Ruby ${rvm_ruby_string} is not installed."
  fi
  exit $result
}
unset previous_rvm_ruby_strings

__rvm_attempt_single_exec

for current_set_ruby in ${rvm_ruby_strings[@]}
do
  __rvm_ruby_do
done

if [[ -n "$rvm_summary_flag" ]] ; then __rvm_summary ; fi
if [[ -n "$rvm_yaml_flag" ]]    ; then __rvm_yaml    ; fi
if [[ -n "$rvm_json_flag" ]]    ; then __rvm_json    ; fi

rvm_hook="after_do" ; source "$rvm_scripts_path/hook"

exit ${#errors[*]}
